package com.jinyou.utils.common;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 不同对象间的的赋值
 * 
 * @author Jahnke 2016年5月28日 16:34:30
 */
public class BeansUtils {

	/**
	 * 复制对象属性
	 * 
	 * @param from
	 * @param to
	 * @param excludsArray
	 *            排除属性列表
	 * @throws Exception
	 */
	public static void bean2Bean(Object from, Object to, String[] excludsArray)
			throws Exception {
		List<String> excludesList = null;
		if (excludsArray != null && excludsArray.length > 0) {
			excludesList = Arrays.asList(excludsArray); // 构造列表对象
		}
		Method[] fromMethods = from.getClass().getDeclaredMethods();
		Method[] toMethods = to.getClass().getDeclaredMethods();
		Method fromMethod = null, toMethod = null;
		String fromMethodName = null, toMethodName = null;
		for (int i = 0; i < fromMethods.length; i++) {
			fromMethod = fromMethods[i];
			fromMethodName = fromMethod.getName();
			if (!fromMethodName.contains("get"))
				continue;
			// 排除列表检测
			if (excludesList != null
					&& excludesList.contains(fromMethodName.substring(3)
							.toLowerCase())) {
				continue;
			}
			toMethodName = "set" + fromMethodName.substring(3);
			toMethod = findMethodByName(toMethods, toMethodName);
			if (toMethod == null)
				continue;
			Object value = fromMethod.invoke(from, new Object[0]);
			if (value == null)
				continue;
			// 集合类判空处理
			if (value instanceof Collection) {
				Collection<?> newValue = (Collection<?>) value;
				if (newValue.size() <= 0)
					continue;
			}
			toMethod.invoke(to, new Object[] { value });
		}
	}

	/**
	 * @方法名: findMethodByName
	 * @方法描述:从方法数组中获取指定名称的方法
	 * @方法参数 @param methods
	 * @方法参数 @param name
	 * @方法参数 @return
	 * @返回类型 Method
	 * @throws
	 */
	private static Method findMethodByName(Method[] methods, String name) {
		for (int j = 0; j < methods.length; j++) {
			if (methods[j].getName().equals(name))
				return methods[j];
		}
		return null;
	}

	/**
	 * @方法名: beanToHashMap
	 * @方法描述:将JavaBean对象转成map集合
	 * @方法参数 @param obj
	 * @方法参数 @return
	 * @返回类型 HashMap<String,Object>
	 * @throws
	 */
	public static HashMap<String, Object> beanToHashMap(Object obj) {
		if (obj != null) {
			HashMap<String, Object> map = new HashMap<String, Object>();
			BeanInfo beanInfo;
			try {
				beanInfo = Introspector.getBeanInfo(obj.getClass());
				PropertyDescriptor[] propertyDescriptors = beanInfo
						.getPropertyDescriptors();
				for (PropertyDescriptor property : propertyDescriptors) {
					String key = property.getName();
					if (key.compareToIgnoreCase("class") == 0) {
						continue;
					}
					Method getter = property.getReadMethod();
					Object value = getter != null ? getter.invoke(obj) : null;
					map.put(key, value);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return map;
		} else {
			return null;
		}
	}

	/**
	 * @方法名: beanToHashMap
	 * @方法描述:将JavaBean转换成Map结构数据
	 * @方法参数 @param objs
	 * @方法参数 @return
	 * @返回类型 List<HashMap<String,Object>>
	 * @throws
	 */
	public static List<HashMap<String, Object>> beanToHashMap(List<Object> objs) {
		if (objs != null && objs.size() > 0) {
			List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
			for (int i = 0; i < objs.size(); i++) {
				Object obj = objs.get(i);
				if (obj != null) {
					HashMap<String, Object> map = new HashMap<String, Object>();
					BeanInfo beanInfo;
					try {
						beanInfo = Introspector.getBeanInfo(obj.getClass());
						PropertyDescriptor[] propertyDescriptors = beanInfo
								.getPropertyDescriptors();
						for (PropertyDescriptor property : propertyDescriptors) {
							String key = property.getName();
							if (key.compareToIgnoreCase("class") == 0) {
								continue;
							}
							Method getter = property.getReadMethod();
							Object value = getter != null ? getter.invoke(obj)
									: "";
							map.put(key, value);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					list.add(map);
				} else {
					return null;
				}
			}
			return list;
		} else {
			return null;
		}
	}

	/**
	 * @方法名: ListMap2JavaBean
	 * @方法描述:根据List<Map<String, Object>>数据转换为JavaBean数据
	 * @方法参数 @param clazz
	 * @方法参数 @param datas
	 * @方法参数 @return
	 * @返回类型 List<? extends Object>
	 * @throws
	 */
	public static List<? extends Object> ListMap2JavaBean(Class clazz,
			List<HashMap<String, Object>> datas) {
		// 根据类名来创建Class对象
		Class c = null;
		List<Object> list = new ArrayList<Object>();
		try {
			c = Class.forName(clazz.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}

		Method[] methods = c.getMethods();

		// 创建类的实例
		if (datas != null && datas.size() > 0) {
			for (int i = 0; i < datas.size(); i++) {
				Map<String, Object> map = datas.get(i);
				try {
					Object obj = c.newInstance();
					org.apache.commons.beanutils.BeanUtils.populate(obj, map);
					list.add(obj);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			return list;
		} else {
			return null;
		}
	}

	/**
	 * @方法名: Map2JavaBean
	 * @方法描述:根据map转换成JavaBean
	 * @方法参数 @param clazz
	 * @方法参数 @param data
	 * @方法参数 @return
	 * @返回类型 Object
	 * @throws
	 */
	public static Object Map2JavaBean(Class clazz, HashMap<String, Object> data) {
		// 根据类名来创建Class对象
		Class c = null;
		List<Object> list = new ArrayList<Object>();
		try {
			c = Class.forName(clazz.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}

		Method[] methods = c.getMethods();

		// 创建类的实例
		if (data != null) {
			try {
				Object obj = c.newInstance();
				org.apache.commons.beanutils.BeanUtils.populate(obj, data);
				return obj;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
